#include "Acceptor.h"
#include <assert.h>
#include "EventLoop.h"
#include "Log.h"

namespace dsth {

Acceptor::Acceptor(EventLoop* loop, const InetSocketAddress& addr)
    : accept_socket_(), 
    loop_(loop), 
    channel_(accept_socket_.GetFd(), loop_) {
    accept_socket_.SetReuseAddr(true);
    accept_socket_.Bind(addr);
    channel_.SetReadHandler(std::make_pair(this, &Acceptor::OnReadEnabled));
}


Acceptor::~Acceptor() {
    LOG_TRACE("[Acceptor::~Acceptor]");
}

void Acceptor::Listen() {
    // EventLoop may be not looping.
    //assert(loop_->IsInLoopThread());
    accept_socket_.Listen();
    channel_.EnableReading();
    LOG_INFO("[Acceptor::Listen] listen started.");
}

void Acceptor::OnReadEnabled(Timestamp recv_time) {
    assert(loop_->IsInLoopThread());
    // handle new connection
    LOG_TRACE("[Acceptor::OnReadEnabled]");
    assert(accept_handler_);
    InetSocketAddress peer_addr(0);
    int fd = accept_socket_.Accept(peer_addr);
    if (fd >= 0) {
        accept_handler_(fd, peer_addr);
    }
    else {
        // TODO: special problem of accept()
        LOG_ERROR("[Acceptor::OnReadEnabled] fd:%d.", fd);
    }
}
    
} // namespace
